#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Last Update:

'''大漠插件接口
'''

__revision__ = '0.1'
__author__ = 'lxd'
import win32com.client, pywintypes, pythoncom
import os
import tools
import config
import time
import win32gui

class Dmsoft():
    '''大漠插件接口
    '''
    def __init__(self,log):
        self.log = log
        self.dm = self.__registerDmsoft()
        self.__setPath()
        self.initCenterPos()
        self.hwnd = 0

    def __registerDmsoft(self):
        '''注册插件
        '''
        pythoncom.CoInitialize()
        try:
            dm = win32com.client.Dispatch('dm.dmsoft')
        except pywintypes.com_error:
            command = 'regsvr32 /s res.dll'
            if os.system(command) == 0:  
                dm = win32com.client.Dispatch('dm.dmsoft')
                assert(dm.Ver == '1.1043')
                return dm
            else:  
                self.log.error('regsver32 error')
        else:
            assert(dm.Ver == '1.1043')
            return dm

    def __setPath(self):
        '''设置路径
        '''
        base_path = os.getcwd()
        self.dm.SetPath(base_path)

    def initCenterPos(self):
        """还原中心点
        """
        self.origin_x, self.origin_y = 0, 0

    def setCenterPos(self, *args):
        """设置中心点坐标
        """
        x, y = self.__parsePoint(*args)
        self.origin_x = x
        self.origin_y = y

##########窗口函数##########
    def activeWindow(self):
        self.dm.SetWindowState(self.hwnd, 1)

    def bindWindow(self):
        '''绑定窗口，后台使用
        '''
        self.dm.BindWindow(self.hwnd,'gdi','windows','windows')

    def getSon(self):
        """获取第一个子窗口句柄
        """
        self.hwnd = self.dm.GetWindow(self.hwnd, 1)
        return self

    def getSonByClass(self, class_name):
        """根据class获取子窗口
        """
        hwnd = self.dm.GetWindow(self.hwnd, 1)#获取第一个子窗口句柄
        while hwnd:
            hwnd = self.dm.GetWindow(hwnd, 4)#获取下一个窗口句柄
            if self.dm.GetWindowClass(hwnd) == class_name:
                self.hwnd = hwnd
                break
        return self

    def getWindowClass(self):
        """得到窗口的类名
        """
        return self.dm.GetWindowClass(self.hwnd)


##########内部辅助函数##########
    def __getRealPoint(self, x, y):
        """由偏移获得点实际坐标
        """
        x += self.origin_x
        y += self.origin_y
        return x, y

    def __getRealRegion(self, left, top, right, bottom):
        """由偏移获得区域实际坐标, 如果是全局范围则不用偏移
        """
        if not (left == config.left and top == config.top and right == config.right and bottom == config.bottom): 
            left += self.origin_x
            top += self.origin_y
            right += self.origin_x
            bottom += self.origin_y
        return left, top, right, bottom

    def __progressPoint(self, point):
        """处理dmsoft返回的点坐标
        """
        if point == '-1|-1':
            return False
        else:
            p = map(int, point.split('|'))
            return (p[0]-self.origin_x, p[1]-self.origin_y)

    def __progressPoint2(self,point):
        """处理dmsoft返回的点坐标(三维的)
        """
        if point == '-1|-1|-1':
            return False
        else:
            p = map(int, point.split('|'))[1:]
            return (p[0]-self.origin_x, p[1]-self.origin_y)

    def __progressPoints(self, points):
        '''处理dmsoft返回的多点坐标
        '''
        if points:
            point = points.split('|')
            xs = map(int, point[0].split(','))
            ys = map(int, point[1].split(','))

            r = []
            for i in range(len(xs)):
                r.append((xs[i]-self.origin_x, ys[i]-self.origin_y))
            return r
        else:
            return False

    def __parsePoint(self, *args):
        """为了方便输入point或者x, y
        """
        if len(args) == 1:
            x, y = args[0][0], args[0][1]
        elif len(args) == 2:
            x, y = args[0], args[1]
        else:
            raise Exception, 'args should be 1 or 2'
        return x, y
##########文字识别##########
    def setDict(self, dicts):
        '''设置词典
        '''
        for i, dict in enumerate(dicts):
            self.dm.SetDict(i,dict)

    def useDict(self,index):
        '''使用字典
        '''
        return self.dm.UseDict(index)

    def findStr(self,str,left = config.left,top = config.top,right = config.right,bottom = config.bottom,color = 'ffffff-000000',sim = 1.0):
        '''区域内查找字符串，默认字符串颜色为白色，无偏色
        '''
        left, top, right, bottom = self.__getRealRegion(left, top, right, bottom)
        r = self.dm.FindStrE(left,top,right,bottom,str,color,sim)
        return self.__progressPoint(r)

    def findStrs(self,str,left = config.left,top = config.top,right = config.right,bottom = config.bottom,color = 'ffffff-000000',sim = 1.0):
        '''区域内查找字符串的多个坐标，默认字符串颜色为白色，无偏色
        '''
        left, top, right, bottom = self.__getRealRegion(left, top, right, bottom)
        r = self.dm.FindStrEx(left,top,right,bottom,str,color,sim)
        return self.__progressPoints(r)

    def ocr(self,left = config.left,top = config.top,right = config.right,bottom = config.bottom,color = 'ffffff-000000',sim = 1.0):
        '''区域内识别字符串，默认字符串颜色为白色，无偏色
        '''
        left, top, right, bottom = self.__getRealRegion(left, top, right, bottom)
        r = self.dm.Ocr(left,top,right,bottom,color,sim)
        return r
##########颜色识别##########
    def getColor(self,*args):
        '''RGB format
        '''
        x, y = self.__parsePoint(*args)
        x, y = self.__getRealPoint(x, y)
        return self.dm.GetColor(x,y).lower()
        
    def findColor(self,color,left = config.left,top = config.top,right = config.right,bottom = config.bottom,sim = 1.0,dir = 0):
        '''查找指定区域内某颜色的坐标,颜色格式"RRGGBB-DRDGDB",dir = 0为从左到右,从上到下查找，dir = 4为从中心往外查找
        '''
        left, top, right, bottom = self.__getRealRegion(left, top, right, bottom)
        r = self.dm.FindColorE(left,top,right,bottom,color,sim,dir)
        return self.__progressPoint(r)

    def findColors(self,color,left = config.left,top = config.top,right = config.right,bottom = config.bottom,sim = 1.0,dir = 0):
        '''查找指定区域内某颜色的多个坐标,颜色格式"RRGGBB-DRDGDB",dir = 0为从左到右,从上到下查找，dir = 4为从中心往外查找
        '''
        left, top, right, bottom = self.__getRealRegion(left, top, right, bottom)
        r = self.dm.FindColorEx(left,top,right,bottom,color,sim,dir)
        return self.__progressPoints(r)

    def findMultiColor(self,colors, left = config.left,top = config.top,right = config.right,bottom = config.bottom,sim = 1.0,dir = 0):
        '''根据指定区域内的多个颜色值查找坐标,颜色格式"RRGGBB-DRDGDB",dir = 0为从左到右,从上到下查找，dir = 4为从中心往外查找
        '''
        left, top, right, bottom = self.__getRealRegion(left, top, right, bottom)
        color,offset_color = tools.splitMultiColorFromStr(colors)
        r = self.dm.FindMultiColorE(left,top,right,bottom,color,offset_color,sim,dir)
        return self.__progressPoint(r)

    def findMultiColors(self,colors,left = config.left,top = config.top,right = config.right,bottom = config.bottom, sim = 1.0,dir = 0):
        '''根据指定区域内的多个颜色值查找多个坐标,颜色格式"RRGGBB-DRDGDB",dir = 0为从左到右,从上到下查找，dir = 4为从中心往外查找
        '''
        left, top, right, bottom = self.__getRealRegion(left, top, right, bottom)
        color,offset_color = tools.splitMultiColorFromStr(colors)
        r = self.dm.FindMultiColorEx(left,top,right,bottom,color,offset_color,sim,dir)
        return self.__progressPoints(r)

    def findPic(self, pic_name, left = config.left,top = config.top,right = config.right,bottom = config.bottom,delta_color = '000000', sim = 1.0, dir = 0):
        """查找指定区域内的图片,位图必须是24位色格式,支持透明色,返回X Y坐标.
        """
        left, top, right, bottom = self.__getRealRegion(left, top, right, bottom)
        r = self.dm.FindPicE(left, top, right, bottom, pic_name, delta_color, sim, dir)
        return self.__progressPoint2(r)

##########键盘鼠标##########
    def getMousePos(self):
        """得到鼠标屏幕坐标
        """
        return win32gui.GetCursorPos()

    def getRect(self):
        """得到窗口坐标
        """
        return win32gui.GetWindowRect(self.hwnd)

    def getClientPos(self):
        """得到鼠标的客户坐标
        """
        left, top, right, bottom = self.getRect()
        x, y = self.getMousePos()
        x -= left
        y -= top
        return x, y

    def moveTo(self,*args):
        '''参数为(x, y)或x, y
        '''
        x, y = self.__parsePoint(*args)
        x, y = self.__getRealPoint(x, y)
        self.dm.MoveTo(x,y)
        tools.sleep()
        return x, y

    def click(self,*args):
        pos = self.moveTo(*args)
        self.dm.LeftClick
        self.log.debug('click on %s' %str(pos))
        tools.sleep()

    def drag(self, x, y, restrict = False):
        """拖动x, y距离(相对距离), 左上拖动为负，水平为x竖直为y
        如果x, y是通过变量赋值的，而且其大小可能会大于可拖动距离，则应设restrict为True
        """
        if restrict:
            if hasattr(config, 'drag_left') and hasattr(config, 'drag_left') \
                and hasattr(config, 'drag_left') and hasattr(config, 'drag_left'):
                x = x > 0 and config.drag_right or config.drag_left
                y = y > 0 and config.drag_bottom or config.drag_top
                self.log.debug('restrict mode:drag:%s, %s' %(x, y))
        else:
            self.log.debug('normal mode:drag:%s, %s' %(x, y))
        self.dm.LeftDown
        self.dm.MoveR(x,y)
        self.dm.LeftUp
        #速度太快颜色不会变的
        time.sleep(1)

    def isColor(self,x,y,color):
        '''判断(x,y)处的颜色是否为color
        '''
        return self.getColor(x,y) == color.lower()

##########点完后条件如果会变那么应该wait = True##########
    def clickIfColor(self,x,y,color, wait=False, *wait_colors):
        """可以设置该点会出现的多种颜色, 在出现这些颜色时都需要等待并且重复点击
        """
        if self.isColor(x,y,color):
            self.click(x,y)
            if wait:
                while self.isColor(x, y, color):
                    self.click(x,y)
                    tools.sleep()

                if wait_colors:
                    for wait_color in wait_colors:
                        while self.isColor(x, y, wait_color):
                            self.click(x,y)
                            tools.sleep()
            return True
        else:
            real_color = self.getColor(x, y)
            x, y = self.__getRealPoint(x, y)
            self.log.debug('(%s,%s) color is not %s,but %s' %(x, y, color, real_color))
            return False

    def clickIfNotColor(self,x,y,color):
        """这个暂时没有暂停
        """
        if not self.isColor(x,y,color):
            self.click(x,y)
            return True
        else:
            return False

    def clickIfFindPic(self, pic_name, left = config.left,top = config.top,right = config.right,bottom = config.bottom,delta_color = '000000', sim = 1.0, dir = 0, wait=False):
        """如果找到图片，就偏移10像素再点, 如果wait找到其它也点
        """
        def offsetClick(point):
            x = point[0] + 10
            y = point[1] + 10
            self.click(x, y)

        point = self.findPic(pic_name, left, top, right, bottom, delta_color, sim, dir)
        if point:
            offsetClick(point)
            if wait:
                while True:
                    new_point = self.findPic(pic_name, left, top, right, bottom, delta_color, sim, dir)
                    if new_point:
                        offsetClick(new_point)
                        tools.sleep()
                    else:
                        break
            return True
        else:
            self.log.debug('can not find picture %s' %pic_name)
            return False


    def clickIfFindMultiColor(self,colors, left = config.left,top = config.top,right = config.right,bottom = config.bottom,sim = 1.0,dir = 0, wait=False):
        '''如果通过多点颜色找到坐标就点, 如果wait找到其他也点
        '''
        point = self.findMultiColor(colors, left,top,right,bottom,sim,dir)
        if point:
            self.click(point)
            if wait:
                while True:
                    new_point = self.findMultiColor(colors, left,top,right,bottom,sim,dir)
                    if new_point:
                        self.click(new_point)
                        tools.sleep()
                    else:
                        break
            return True
        else:
            self.log.error('can not find multicolor %s' %colors)
            return False

def testDm():
    hwnd= '1d0c16'
    hwnd= int(hwnd,16)

    dm= Dmsoft(config.log)
    dm.hwnd = hwnd
    dm.bindWindow()
    
    dicts= [r'static/songti9_7.txt']
    dm.setDict(dicts)
    dm.useDict(0)
    return dm
dm = testDm()

if __name__ == '__main__':
    print 'k'
    print dm.clickIfFindMultiColor('00c5fb,1|10|00fdc7')



